/*
 * DBUtil.java
 *
 * Created on 2006\uB144 3\uC6D4 29\uC77C (), ???? 9:31
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */
package com.zll.framework.db;


import java.sql.*;
import java.util.*;
import java.io.*;
import javax.naming.*;
import javax.sql.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import java.net.URL;

import com.zll.framework.conf.Configuration;
import com.zll.framework.util.*;

/**
 *
 * @author eastar
 */
public class SqlParser
{

	public static HashMap getSql(String xmlName, String sqlName, HashMap params)
	throws Exception
	{
		HashMap queryMap = new HashMap();
		String query = "";
		ArrayList bindList = new ArrayList();

		try
		{
			// get query in xml
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();   //XML을 다루는 CLASS
			DocumentBuilder parser = dbf.newDocumentBuilder();                   //XML을 다루는 CLASS
			Document doc  = parser.parse(new FileInputStream(Configuration.getHomePath()+"/WEB-INF/sql/"+Configuration.getDbName()+xmlName));       //sql문이 존재하는 해당 XML 파일을 읽어 들인다.

			Element root = doc.getDocumentElement();
			NodeList nodeLst = root.getElementsByTagName(sqlName);  //sqlName에 해당하는 SQL의 tag들 모두  READ한다.
			Node node = nodeLst.item(0);                            //동방장비시스템에서는 sqlName이 중복존재하지 않기 때문에 item(0)으로 첫번째 값만 가져오면 됨

			if (node == null) {
				throw new Exception(xmlName + "." + sqlName + "이 존재하지 않습니다");
			}

			NodeList children = node.getChildNodes();               //sqlName에서 가지고 있는 <AUTHOR>..<DESC>..<SQL> 이 3가지가 읽혀 진다.

			for (int i = 0; i < children.getLength(); i++) {        //<AUTHOR>..<DESC>..<SQL>이 3가지중 <SQL>만 필요하기 때문에 for문으로 찾는다.
				Node child = children.item(i);
				if ("sql".equals(child.getNodeName())) {
					NodeList children2 = child.getChildNodes();     //실재 SQL 문장을 RETURN
					Node sql = children2.item(1);
					if (sql.getNodeType() == Node.CDATA_SECTION_NODE) { //Node.CDATA_SECTION_NODE 는    <![CDATA[  를 말함
						query = sql.getNodeValue().trim();
					}
				}
			}

			int sPos = -1;
			int ePos = -1;

			// change query []
			// [#컬럼명#], [$컬럼명$] 이 존재 시 -> 해당 값으로   변경한다.
			// 변경이 완료 되면 []는 살아 지고 해당 값(#칼럼명#, $칼럼명$)만 남는다.
			sPos = query.indexOf("[");
			while (sPos > -1) {
				ePos = query.indexOf("]", sPos+1);

				int optionPos = query.indexOf("#", sPos);


				String optionStr = "#";

				//2010.12.16 [] 안에 $$만 있을 경우도 처리되도록 변경. by eastar
				if (optionPos < 0 || optionPos > ePos) {
					optionPos = query.indexOf("$", sPos);
					optionStr = "$";
				}


//				int optionPos_sharp  = query.indexOf("#", sPos);
//				int optionPos_doller = query.indexOf("$", sPos);
//				if( optionPos_sharp > -1 && optionPos_doller > -1 && optionPos_sharp > optionPos_doller ) {
//					optionPos = query.indexOf("$", sPos);
//					optionStr = "$";
//				}

				String key = query.substring(optionPos+1, query.indexOf(optionStr, optionPos+1));  //##, $$안에 있는 컬럼또는 변수명

				String value = StringUtil.nvl(params.get(key));
				if (value.equals("")) {
					query = query.substring(0, sPos) + query.substring(ePos+1);  //null일 경우 지움
				} else {
					query = query.substring(0, sPos) + " " + query.substring(sPos+1, ePos) + query.substring(ePos+1); //값이 존재 시 교체
				}
				sPos = query.indexOf("[");
			}

			// change query
			// $컬럼명$ : 이 존재 시 -> 해당 값으로   변경한다.
			// 변경이 완료 되면 $$ 는 살아 지고 해당 값만 남는다.
			sPos = query.indexOf("$");
			while (sPos > -1) {
				String key = query.substring(sPos+1, query.indexOf("$", sPos+1));
				String value = StringUtil.nvl(params.get(key));
				query = StringUtil.replaceAll(query, "$"+key+"$", value);
				sPos = query.indexOf("$");
			}

			// change query ##
			// #컬럼명# : 이 존재 시 -> 컬럼명을 ? 로 변경한다.
			// 차후 ? 를 binding 시키기 위해서 이다.
			sPos = query.indexOf("#");
			while (sPos > -1) {
				String key = query.substring(sPos+1, query.indexOf("#", sPos+1));
				Object obj = params.get(key);
				if (obj instanceof java.lang.Integer) {
					bindList.add(obj);
					query = query.substring(0, sPos) + "?" + query.substring(sPos+key.length()+2);
				} else {
					String value = StringUtil.nvl(params.get(key));
					String[] values = null;
					if (value.indexOf(":") > -1) {
						values = value.split(":");
					}
					if (values == null) {
						bindList.add(value);
						query = query.substring(0, sPos) + "?" + query.substring(sPos+key.length()+2);
					} else {
						String inQuery = "''";
						for (int i = 0; i < values.length; i++) {
							bindList.add(values[i]);
							inQuery += ",?";
						}
						query = query.substring(0, sPos) + inQuery + query.substring(sPos+key.length()+2);
					}
				}
				sPos = query.indexOf("#");
			}

			queryMap.put("query", query);      //Preparestament에 넣을 SQL문장을 만듬
			queryMap.put("bindList", bindList);//Preparestament에 바인드될 value값들

		}catch(Exception e){
			e.printStackTrace();
			throw new Exception("DAO error 1");
		}finally{

		}

		return queryMap;
	}



	public static HashMap getSql(String xmlName, String sqlName, String param)
	throws Exception
	{
		HashMap queryMap = new HashMap();
		String query = "";
		ArrayList bindList = new ArrayList();

		try
		{
			//File curDir = new File(".");
			//String home = curDir.getCanonicalPath();


			// get query in xml
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder parser = dbf.newDocumentBuilder();
			Document doc  = parser.parse(new FileInputStream(Configuration.getHomePath()+"/WEB-INF/sql/"+Configuration.getDbName()+xmlName));

			Element root = doc.getDocumentElement();
			NodeList nodeLst = root.getElementsByTagName(sqlName);
			Node node = nodeLst.item(0);

			NodeList children = node.getChildNodes();

			for (int i = 0; i < children.getLength(); i++) {
				Node child = children.item(i);
				if ("sql".equals(child.getNodeName())) {
					NodeList children2 = child.getChildNodes();
					Node sql = children2.item(1);
					if (sql.getNodeType() == Node.CDATA_SECTION_NODE) {
						query = sql.getNodeValue().trim();
					}
				}
			}

			//System.out.println("before query[" + query + "]");

			int sPos = -1;
			int ePos = -1;

			// change query $$
			sPos = query.indexOf("$");
			while (sPos > -1) {
				String key = query.substring(sPos+1, query.indexOf("$", sPos+1));
				String value = StringUtil.nvl(param);
				query = StringUtil.replaceAll(query, "$"+key+"$", value);
				sPos = query.indexOf("$");
			}

			// change query []
			sPos = query.indexOf("[");
			while (sPos > -1) {
				ePos = query.indexOf("]", sPos+1);
				int optionPos = query.indexOf("#", sPos);
				String key = query.substring(optionPos+1, query.indexOf("#", optionPos+1));
				String value = StringUtil.nvl(param);
				if (value.equals("")) {
					query = query.substring(0, sPos) + query.substring(ePos+1);
				} else {
					query = query.substring(0, sPos) + " " + query.substring(sPos+1, ePos) + query.substring(ePos+1);
				}
				sPos = query.indexOf("[");
			}

			// change query ##
			sPos = query.indexOf("#");
			while (sPos > -1) {
				String key = query.substring(sPos+1, query.indexOf("#", sPos+1));
				bindList.add(param);
				query = query.substring(0, sPos) + "?" + query.substring(sPos+key.length()+2);
				sPos = query.indexOf("#");
			}

//			System.out.println("\n["+xmlName+"] "+sqlName+"===================================================================");
//			System.out.println("            " + query);
//			System.out.println("==============================================================================\n");

			queryMap.put("query", query);
			queryMap.put("bindList", bindList);

		}catch(Exception e){
			e.printStackTrace();
			throw new Exception("DAO error 1");
		}finally{

		}

		return queryMap;
	}


	public static HashMap getUpdateSql(String xmlName, String sqlName, HashMap params)
	throws Exception
	{
		HashMap queryMap = new HashMap();
		String query = "";
		ArrayList bindList = new ArrayList();

		try
		{
			// get query in xml
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder parser = dbf.newDocumentBuilder();
			Document doc  = parser.parse(new FileInputStream(Configuration.getHomePath()+"/WEB-INF/sql/"+Configuration.getDbName()+xmlName));

			Element root = doc.getDocumentElement();
			NodeList nodeLst = root.getElementsByTagName(sqlName);
			Node node = nodeLst.item(0);

			NodeList children = node.getChildNodes();

			for (int i = 0; i < children.getLength(); i++) {
				Node child = children.item(i);
				if ("sql".equals(child.getNodeName())) {
					NodeList children2 = child.getChildNodes();
					Node sql = children2.item(1);
					if (sql.getNodeType() == Node.CDATA_SECTION_NODE) {
						query = sql.getNodeValue().trim();
					}
				}
			}

			//System.out.println("before query[" + query + "]");

			int sPos = -1;
			int ePos = -1;

			// change query $$
			sPos = query.indexOf("$");
			while (sPos > -1) {
				String key = query.substring(sPos+1, query.indexOf("$", sPos+1));
				String value = StringUtil.nvl(params.get(key));
				query = StringUtil.replaceAll(query, "$"+key+"$", value);
				sPos = query.indexOf("$");
			}

			// change query []
			sPos = query.indexOf("[");
			while (sPos > -1) {
				ePos = query.indexOf("]", sPos+1);
				int optionPos = query.indexOf("#", sPos);
				String key = query.substring(optionPos+1, query.indexOf("#", optionPos+1));
				String value = (String)params.get(key);
				if (value == null) {
					query = query.substring(0, sPos) + query.substring(ePos+1);
				} else {
					query = query.substring(0, sPos) + " " + query.substring(sPos+1, ePos) + query.substring(ePos+1);
				}
				sPos = query.indexOf("[");
			}

			// change query ##
			sPos = query.indexOf("#");
			while (sPos > -1) {
				String key = query.substring(sPos+1, query.indexOf("#", sPos+1));
				bindList.add(params.get(key));
				query = query.substring(0, sPos) + "?" + query.substring(sPos+key.length()+2);
				sPos = query.indexOf("#");
			}

//			System.out.println("\n["+xmlName+"] "+sqlName+"===================================================================");
//			System.out.println("            " + query);
//			System.out.println("==============================================================================\n");

			queryMap.put("query", query);
			queryMap.put("bindList", bindList);

		}catch(Exception e){
			e.printStackTrace();
			throw new Exception("DAO error 1");
		}finally{

		}

		return queryMap;
	}

}
